package cn.edu.lcu.cs.javateaching.io;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

/**
 * 文件工具类
 * 
 * @author Ling
 *
 */
public class FileUtil {
	/**
	 * 获取文件扩展名，比如文件名为 abc.jpg，返回扩展文件名 .jpg
	 * 
	 * @param filename
	 * @return
	 */
	public static String getExtension(String filename) {
		String extension = null;
		try {
			extension = filename.substring(filename.lastIndexOf("."));
		} catch (Exception e) {
//			e.printStackTrace();
		}
		return extension;
	}

	/**
	 * 文件深拷贝
	 * <ul>
	 * <li>如果源是文件，直接拷贝到目标文件夹</li>
	 * <li>如果源是文件夹，深度拷贝源文件夹到目标文件夹，包括源文件夹的所有子文件夹的内容</li>
	 * </ul>
	 * 
	 * @param source       源文件或源文件夹
	 * @param targetFolder 目标文件夹
	 */
	public static void deepCopy(String source, String targetFolder) {
		System.out.println("Copying ...\n");
		try {
			Path sourcePath = Paths.get(source);
			Path targetPath = Paths.get(targetFolder);
			// 遍历原始文件夹，深度遍历目录树
			// 可以指定深度，本例为10级。
			// 缺省是 Integer.MAX_VALUE，相当于无限级
			Files.walk(sourcePath, 10).forEach(fromPath -> {
				// 计算当前处理路径与原始路径的相对路径 sourcePath.relativize(fromPath)
				// 路径表决：将计算出的相对路径与目标路径拼接成最终目标路径
				Path toPath = targetPath.resolve(sourcePath.relativize(fromPath));
				System.out.println(fromPath + "\t --> \t" + toPath);
				try {
					// 如果是目录，就创建目录
					if (Files.isDirectory(fromPath)) {
						Files.createDirectories(toPath);
					} else {
						// 否则，复制文件，若目标存在就替换
						Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			});
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 列目录，包括子目录的内容
	 * 
	 * @param folderName 文件夹名称
	 */
	public static void deepDir(String folderName) {
		Path path = Paths.get(folderName);
		if (Files.notExists(path) || !Files.isDirectory(path)) {
			return;
		}
		try {
			Files.walk(path).forEach(System.out::println);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 单文件拷贝
	 * 
	 * @param sourceFileName 源文件名称
	 * @param targetFolder   目标文件夹
	 */
	public static void copy(String sourceFileName, String targetFolder) {
		try {
			Path fromPath = Paths.get(sourceFileName);
			Path toPath = Paths.get(targetFolder);
			// 如果源文件是常规文件就拷贝
			if (Files.isRegularFile(fromPath)) {
				if (Files.notExists(toPath)) {
					Files.createDirectories(toPath);
				}
				toPath = toPath.resolve(fromPath.getFileName());
				Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 删除文件或（空）目录
	 * 
	 * @param filename 被删除目录或文件名称
	 */
	public static void del(String filename) {
		File file = new File(filename);
		// File.delete() 可以删除文件与空目录
		if (file.delete()) {
			System.out.println("删除成功：\t" + filename);
		} else {
			System.out.println("删除失败：\t" + filename);
		}
	}

	/**
	 * 深度删除：如果是文件则删除；如果是目录，删除当前目录及子目录所有内容
	 * 
	 * @param filename 被删除文件或目录名称
	 */
	public static void deepDel(String filename) {
		File file = new File(filename);
		if (file.isDirectory()) { // 如果是目录
			String[] files = file.list();
			if (files != null) { // 如果目录非空，则嵌套调用，深度删除
				String absolutePath = file.getAbsolutePath() + File.separator;
				// 依次删除每个目录项（文件或子目录）
				for (String f : files) {
					deepDel(absolutePath + f);
				}
			}
			// 此时已是空目录，直接删除
			file.delete();
		} else {
			// 如果是文件，直接删除
			file.delete();
		}

	}
}
